﻿using System.Collections.Generic;
using System.Windows;
using Microsoft.Win32;
using WeiBeeCommon.Helpers;
using WeiBeeCommon.Core;
using System;
using System.Threading;
using WeiBeeCommon.DataTypes;
using System.IO;
using System.Xml.Serialization;
using System.Text.RegularExpressions;
using System.Text;

namespace QunFaExpert
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private string adstring = "#v5抢沙发#";
        private string url;// = "http://y182319.51host.net/download/SofaExpert.zip";
        private void lbAdsentence_Click(object sender, RoutedEventArgs e)
        {
            var adSettingDlg = new AdStringSetting(adstring);
            bool? ad = adSettingDlg.ShowDialog();
            if (ad.HasValue && ad.Value)
            {
                MessageBox.Show(adSettingDlg.NewAdString);
            }
        }

        private void btManage_Click(object sender, RoutedEventArgs e)
        {
            var manageWeiBeeDlg = new ManageWeiBee();
            manageWeiBeeDlg.ShowDialog();
        }

        Timer timer;
        // Timer oneminuteTimer;
        const int OneMinute = 60 * 1000;
        private void lbStart_Click(object sender, RoutedEventArgs e)
        {
            int count = InitBatchCommenter();
            if ( count > 0 )
            {
                timer.Change(0, OneMinute / count);
                // oneminuteTimer.Change(0, OneMinute);
            }
        }

        private BatchComment batchComment;
        private int InitBatchCommenter()
        {
            var entities = new EntityHelper().LoadEntities();
            if (entities == null || entities.Count == 0) return 0;
            batchComment = new BatchComment(entities[0].GetWeiBeeSina());
            for (int i = 1; i < entities.Count; i++)
            {
                batchComment.AddOneWeiBee(entities[i].GetWeiBeeSina());
            }
            return entities.Count;
        }

        private string resultstring;
        public void Comments(object progressCallback)
        {
            string extraads = adstring;// string.Format(adstring, url);
            if (hasCommentsLeft)
            {
                try
                {
                    resultstring = batchComment.Comment(extraads);
                }
                catch (Exception ex)
                {
                    SaveLog(string.Format("callstack={0},exinformation={1}",
                        ex.StackTrace, ex.Message));
                    return;
                }
                
                var update = progressCallback as AsyncCallback;
                if (update != null) update(null);
            }
        }

        void Progress(IAsyncResult asyncResult)
        {
            if (successfulCount % 100 == 0) tbResult.Text = string.Empty;
            var s = GetCommentProfile(resultstring);
            if (string.Compare(s, "commented", true) != 0)
            {
                tbResult.Text += s + Environment.NewLine;
            }
            else
            {
                tbResult.Text += ".";
            }
            lbAds.Content = string.Format("成功评论:{0}次，剩余评论{1}次", successfulCount, leftcount);
        }

        #region RandomUrl
        private string orignalurl = "http://y182319.51host.net/download/SofaExpert.zip";
        private int currentChanger = 0;
        private void UrlChanger(object stateInfo)
        {
            url = changes[currentChanger](orignalurl);
            currentChanger = (currentChanger + 1) % changes.Length;
        }

        private delegate string ChangeUrl(string orginal);
        private ChangeUrl[] changes = new ChangeUrl[4];
        private string NoChange(string orginal)
        {
            return orginal;
        }
        private string Bitly(string orginal)
        {
            return Utility.GetShortenUrl(orginal);
        }
        private string Googl(string orginal)
        {
            return "http://t.cn/hBlm6s";
        }
        private string Tcn(string orginal)
        {
            return "http://t.cn/hBluTU";
        }
        private string Urlcn(string orginal)
        {
            return "http://t.cn/hBluUw";
        }
        #endregion RandomUrl

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            tbClientId.Text = string.Format("客户端唯一值:{0}", license.Cpu);
            timer = new Timer(Comments, SyncContextCallback(Progress), Timeout.Infinite, Timeout.Infinite);
            //oneminuteTimer = new Timer(UrlChanger, null, Timeout.Infinite, Timeout.Infinite);
            //changes[0] = Bitly;
            //changes[1] = Googl;
            //changes[2] = Urlcn;
            //changes[3] = Tcn;
        }



        private int leftcount = -1;
        private int successfulCount = 0;
        private bool hasCommentsLeft = true;
        private OnlineLicense license = new OnlineLicense();
        private string GetCommentProfile(string s)
        {
            try
            {
                const string blank = @"<?xml version=""1.0"" encoding=""UTF-8""?>";
                if (s.Length <= blank.Length) return "commented"; // To fix bug //bug if resultstring like "<?xml version="1.0" encoding="UTF-8"?>" the following line will throw exception

                Comment result = null;
                using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(s)))
                {
                    var ser = new XmlSerializer(typeof(Comment));
                    result = ser.Deserialize(ms) as Comment;
                }
                if (result != null)
                {
                    // On successful get comment
                    successfulCount++;
                    if ((successfulCount % 23) == 0)
                    {
                        leftcount = license.GetLeftSofaAmount();
                        if( !(leftcount>0) ) hasCommentsLeft = false;
                    }
                    return string.Format("{0},@{1},时间:{2},内容:{3},评论:{4}",
                                         GetShortTimeString(result.created_at),
                                         result.status.user.name,
                                         GetShortTimeString(result.status.created_at),
                                         GenerateSubstring(result),
                                         result.text.Substring(0, GetLengthNoGreaterThenTen(result.text)));
                }
            }
            catch (Exception ex)
            {
                SaveLog(string.Format("callstack={0},resultstring={1},exinformation={2}",
                    ex.StackTrace, s, ex.Message));
            }
            return "commented";
        }

        private string GetShortTimeString(string longtime)
        {
            Regex re = new Regex("\\d\\d:\\d\\d:\\d\\d", RegexOptions.None);
            MatchCollection mc = re.Matches(longtime);
            return mc[0].Value;
        }

        private int GetLengthNoGreaterThenTen(string p)
        {
            return (p.Length > 10) ? 10 : p.Length;
        }

        private string GenerateSubstring(Comment result)
        {
            return result.status.text.Substring(0, GetLengthNoGreaterThenTen(result.status.text));
        }

        private static void SaveLog(string errorinformation)
        {
            const string logfile = "log.txt";
            using (FileStream fs = new FileStream(logfile, FileMode.OpenOrCreate, FileAccess.Write))
            {
                try
                {
                    string outstring = string.Format("{0} - {1}", DateTime.Now.ToString(), errorinformation);
                    byte[] data = new UTF8Encoding().GetBytes(outstring);
                    fs.Write(data, 0, data.Length);
                }
                catch
                {
                }
            }
        }

        private static AsyncCallback SyncContextCallback(AsyncCallback callback)
        {
            SynchronizationContext sc = SynchronizationContext.Current;
            if (sc == null) return callback;
            return asyncResult => sc.Post(result => callback((IAsyncResult)result), asyncResult);
        }

        private void ButtonTwitter_Click(object sender, RoutedEventArgs e)
        {
            Twitters twForm = new Twitters();
            twForm.ShowDialog();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            var keywordwindow = new KeywordSetting();
            keywordwindow.ShowDialog();
        }

    }
}
